//
//  TinyRadioGroupView.m
//  TinyRadioGroup
//
//  Created by kingdomrain on 2020/6/20.
//  Copyright © 2020 sunline. All rights reserved.
//

#import "TinyRadioGroupView.h"
#import <TinyKern/TinyKern.h>
#import <TinyProtocol/TinyProtocol.h>
#import <TinyUI/TinyUI.h>
#import "TinyRadioGroupConst.h"
#import "TinyRadioGroupViewCell.h"

TINY_NAME_SERVICE(RadioGroup,TinyRadioGroupView)

@interface TinyRadioGroupView()<UIComponentElement,UITableViewDelegate,UITableViewDataSource>
@property(nonatomic,strong)UITableView *tableView;

//RadioGroup的属性
@property(nonatomic,strong)NSMutableArray *dataSource;
@property(nonatomic,copy)NSString *maxSelectNumber;
@property(nonatomic,copy)NSString *selectType;
@property(nonatomic,copy)NSString *disabel;
@property(nonatomic,copy)NSString *textPosition;

@property(nonatomic,strong)NSDictionary *allRadioGroupStyle;  //所有的dependencies/RadioGroup.json中的样式
//RadioGroup支持的样式
@property(nonatomic,assign)CGFloat itemHeight;

@end

@implementation TinyRadioGroupView

-(instancetype)initWithElement:(Element *)element{
    if (self = [super initWithElement:element]) {
       [self componentAttributeChanged];
       [self setComponentAttributes];   //组件未使用数据绑定的的属性先设置
       [self setUp];
    }
    return self;
}

-(void)dealloc{
    NSLog(@"%s",__func__);
}

- (NSString * _Nonnull)getName{
   return @"RadioGroup";
}

- (NSDictionary<NSString *, NSString *> * _Nonnull)getFrameAttrbutes{
    return self.context.element.attributes;
}

- (void)setParam:(NSString * _Nonnull)param value:(id _Nonnull)object{
    if([param isEqualToString:@""] && [object isKindOfClass:[NSDictionary class]]){
        [object enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            [self setParam:key withValue:obj];
        }];
        _allRadioGroupStyle = [[NSDictionary alloc] initWithDictionary:object];
        [self setNeedsLayout];
    }
    else if ([param isEqualToString:@"data"]){
        if ([object isKindOfClass:[NSArray class]]) {
            _dataSource = [[NSMutableArray alloc] initWithArray:object];
            [self.tableView reloadData];
        }
    }
}

-(void)setParam:(NSString *)param withValue:(id)value{
#if DEBUG
    NSLog(@"param : %@ \n value : %@",param,value);
#endif
    if ([param isEqualToString:kTinyRadioGroupStyleNameItemHeight]){
        _itemHeight = [value floatValue];
    }
}

#pragma mark -- 加载数据绑定
- (void)loadMvvmAttribute:(id)value forName:(NSString *)name{
    [super loadMvvmAttribute:value forName:name];
    if ([name isEqualToString:kTinyRadioGroupAttibutNameDataSource]) {
        if ([value isKindOfClass:[NSArray class]]) {
            _dataSource = [self dealwithForOriginDataSource:value];
            [self.tableView reloadData];
        }
    }
    else if ([name isEqualToString:kTinyRadioGroupAttibutNameMaxSelectNumber]){
        _maxSelectNumber = value;
    }
    else if ([name isEqualToString:kTinyRadioGroupAttibutNameSelectType]){
        _selectType = value;
    }
    else if ([name isEqualToString:kTinyRadioGroupAttibutNameDisable]){
        _disabel = value;
        if ([value isEqualToString:@"true"]) {
            self.userInteractionEnabled = NO;
        }
    }
    else if ([name isEqualToString:kTinyRadioGroupAttibutNameTextPosition]){
        _textPosition = value;
    }
}

- (void)viewHierarchyApplyAttributes:(id)attributes {
    NSString *dataSourceexperssion = [self.context.element attributeForName:kTinyRadioGroupAttibutNameDataSource];
    if ([dataSourceexperssion containsString:@"{{"] && [dataSourceexperssion containsString:@"}}"]) {
        if ([attributes valueByExperssion:dataSourceexperssion]) {
            id value = [attributes valueByExperssion:dataSourceexperssion];
            if ([value isKindOfClass:[NSArray class]]) {
                _dataSource = [self dealwithForOriginDataSource:value];
                [self.tableView reloadData];
            }
            else if([value isKindOfClass:[NSString class]]){
                NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
                NSArray *dataSourceArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingFragmentsAllowed error:nil];
                _dataSource = [self dealwithForOriginDataSource:dataSourceArray];
                [self.tableView reloadData];
            }
        }
    }
    [super viewHierarchyApplyAttributes:attributes];
}


/// js传入到底层的数据，进行预处理。检查每项是否有value字段，没有的话，增加value字段。
/// @param dataSource js传入的数据源
-(NSMutableArray *)dealwithForOriginDataSource:(NSArray *)dataSource{
    NSMutableArray *newArray = [[NSMutableArray alloc] init];
    if (dataSource.count == 0) {
        return newArray;
    }
    BOOL isContainValueFiled = YES;
    NSDictionary *item = dataSource[0];  //取出一组组数据进行检查
    NSString *value = item[@"value"];
    if (value == nil) {
        isContainValueFiled = NO;
    }
    if(isContainValueFiled == NO){
        for (NSDictionary *item in dataSource) {
            NSMutableDictionary *newItem = [[NSMutableDictionary alloc] initWithDictionary:item];
            [newItem setValue:@"0" forKey:@"value"];
            [newArray addObject:newItem];
        }
    }
    else{
        newArray = [[NSMutableArray alloc] initWithArray:dataSource];
    }
    return newArray;
}

-(void)setComponentAttributes{
    NSString *maxSelectNumber = self.context.element.attributes[kTinyRadioGroupAttibutNameMaxSelectNumber];
    if (maxSelectNumber && ![maxSelectNumber containsString:@"{{"]) {
        _maxSelectNumber = maxSelectNumber;
    }
    NSString *selectType = self.context.element.attributes[kTinyRadioGroupAttibutNameSelectType];
    if (selectType && ![selectType containsString:@"{{"]) {
        _selectType = selectType;
    }
    NSString *disabel = self.context.element.attributes[kTinyRadioGroupAttibutNameDisable];
    if (disabel && ![disabel containsString:@"{{"]) {
        if ([_disabel isEqualToString:@"true"]) {
            self.userInteractionEnabled = NO;
        }
        _disabel = disabel;
    }
    NSString *textPosition = self.context.element.attributes[kTinyRadioGroupAttibutNameTextPosition];
    if (textPosition) {
        _textPosition = textPosition;
    }
}

-(void)setUp{
    _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
    _tableView.dataSource = self;
    _tableView.delegate = self;
    _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    _tableView.scrollEnabled = YES;    //允许滑动
    _tableView.backgroundColor = [UIColor clearColor];
    [self addSubview:_tableView];
}

-(void)layoutSubviews{
    _tableView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);   //组件的大小赋给tableview
}

#pragma mark -- UITableViewDataSource
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataSource.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellIdentifier = @"TinyRadioGroupViewCell";
    TinyRadioGroupViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[TinyRadioGroupViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    [cell setCellStyleType:_textPosition withStyleSheet:_allRadioGroupStyle];
    [cell refresh:_dataSource[indexPath.row]];
    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if(_itemHeight){
        return _itemHeight;   //如果RadioGroup.json中设置了itemHeight,返回itemHeight作为cell的高度
    }
    NSDictionary *cellData = _dataSource[indexPath.row];
    CGFloat height = [self calculateCellHeight:cellData];
    return ceilf(height);
}

/// 根据data的内容，计算返回当前cell的高度
/// @param data 当前cell的数据
-(CGFloat)calculateCellHeight:(NSDictionary *)data{
    NSString *itemMargin = _allRadioGroupStyle[kTinyRadioGroupStyleNameItemMargin];
    NSString *itemPadding = _allRadioGroupStyle[kTinyRadioGroupStyleNameItemPadding];
    NSString *titleFont = _allRadioGroupStyle[kTinyRadioGroupStyleNameTextFont];
    NSString *radioWidth = _allRadioGroupStyle[kTinyRadioGroupStyleNameRadioWidth];
    NSString *itemIndexSpacing = _allRadioGroupStyle[kTinyRadioGroupStyleNameItemIndexSpacing];
    NSString *radioDrawablePadding = _allRadioGroupStyle[kTinyRadioGroupStyleNameRadioDrawablePadding];
    
    NSArray *itemMarginArray = [itemMargin componentsSeparatedByString:@" "];
    CGFloat itemMarginHeight = [itemMarginArray[0] floatValue] + [itemMarginArray[2] floatValue];
    
    NSArray *itemPaddingArray = [itemPadding componentsSeparatedByString:@" "];
    CGFloat itemPaddingHeight = [itemPaddingArray[0] floatValue] + [itemPaddingArray[2] floatValue];
    
    CGFloat itemContentWidth = self.tableView.frame.size.width - [itemMarginArray[1] floatValue] - [itemMarginArray[3] floatValue];
    CGFloat drawContentWidth = itemContentWidth - [itemPaddingArray[1] floatValue] - [itemPaddingArray[3] floatValue];
    
    CGFloat indexWidth = 0;
    NSString *indexString = data[@"index"];
    if (indexString != nil) {
        indexWidth = [self widthForString:indexString fontSize:[titleFont floatValue] andHeight:50];
    }
    
    CGFloat captionWidth ;
    if ([data[@"value"] isEqualToString:@"1"]) {
        captionWidth = drawContentWidth - [radioWidth floatValue] - indexWidth - [itemIndexSpacing floatValue] -[radioDrawablePadding floatValue];
    }
    else{
        captionWidth = drawContentWidth - indexWidth - [itemIndexSpacing floatValue] - [radioDrawablePadding floatValue];
    }
    CGFloat captionHeight = [self heightForString:data[kTinyRadioGroupRadioCaption] fontSize:[titleFont floatValue] andWidth:captionWidth];
    CGFloat totalHeight = itemMarginHeight + itemPaddingHeight + captionHeight;
    return totalHeight;    
}

#pragma mark -- UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if ([_selectType isEqualToString:kTinyRadioGroupAttibutValueSingleSelect]) {      //单选
        for (NSInteger i=0; i<_dataSource.count; i++) {
            if (i == indexPath.row) {
                NSMutableDictionary *item = [[NSMutableDictionary alloc] initWithDictionary:_dataSource[indexPath.row]];
                NSString *value = [item objectForKey:kTinyRadioGroupRadioValue];
                if ([value isEqualToString:kTinyRadioGroupRadioUnCheckStatus]) {
                    [item setObject:kTinyRadioGroupRadioCheckStatus forKey:kTinyRadioGroupRadioValue];
                }
//                else if([value isEqualToString:kTinyRadioGroupRadioCheckStatus]){
//                    [item setObject:kTinyRadioGroupRadioUnCheckStatus forKey:kTinyRadioGroupRadioValue];
//                }
                _dataSource[indexPath.row] = item;
            }
            else{
                 NSMutableDictionary *item = [[NSMutableDictionary alloc] initWithDictionary:_dataSource[i]];
                 [item setObject:kTinyRadioGroupRadioUnCheckStatus forKey:kTinyRadioGroupRadioValue];
                _dataSource[i] = item;
            }
        }
    }
    else if([_selectType isEqualToString:kTinyRadioGroupAttibutValueMultiSelect]){     //多选
        NSMutableDictionary *item = [[NSMutableDictionary alloc] initWithDictionary:_dataSource[indexPath.row]];
        NSString *value = [item objectForKey:kTinyRadioGroupRadioValue];
        if ([value isEqualToString:kTinyRadioGroupRadioCheckStatus]) {
           [item setObject:kTinyRadioGroupRadioUnCheckStatus forKey:kTinyRadioGroupRadioValue];
           _dataSource[indexPath.row] = item;
        }
        else{
            NSInteger selectNum = 0;
             for (NSDictionary *item in _dataSource) {
                 NSString *value = [item objectForKey:kTinyRadioGroupRadioValue];
                 if ([value isEqualToString:kTinyRadioGroupRadioCheckStatus]) {
                     selectNum++;
                 }
            }
            if (selectNum < [_maxSelectNumber integerValue]) {
               [item setObject:kTinyRadioGroupRadioCheckStatus forKey:kTinyRadioGroupRadioValue];
               _dataSource[indexPath.row] = item;
            }
            else{
                //TODO: 可以排除不能再选择更多的错误提示，后期再完善
            }
        }
    }
    [self.tableView reloadData];   //数据源已经更新，更新tableview
    [self radioStateCallback];
}

-(void)radioStateCallback{
    //抛出到监听事件的回调
    JSValue *script = [self.context.element.eventDictinoary objectForKey:kTinyRadioGroupEventListenerValueChanged];
    if (script) {
        [self callbackToJSContext:script];
    }
    //触发属性绑定的JS方法
    NSString *valueChanged = self.context.element.attributes[kTinyRadioGroupEventListenerValueChanged];
    JSValue *valueChangedJSValue =  self.context.element.document.context.jsContext[valueChanged];
    if (!valueChangedJSValue.isUndefined && !valueChangedJSValue.isNull) {
        [self callbackToJSContext:valueChangedJSValue];
    }
}

-(void)callbackToJSContext:(JSValue *)script{
    NSMutableArray *values = [[NSMutableArray alloc] init];
    for (NSDictionary *item in _dataSource) {
        NSString *value = item[@"value"];
        if ([value isEqualToString:@"1"]) {
            [values addObject:item];   //和安卓统一，只抛出选中项的数据
        }
    }
    [script callWithArguments:@[values]];
}

-(float)heightForString:(NSString *)value fontSize:(float)fontSize andWidth:(float)width
{
    CGSize strSize = CGSizeMake(width, CGFLOAT_MAX);
    NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
    CGFloat stringHeight = 0;
    if (value) {
        CGRect rect = [value boundingRectWithSize:strSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
        stringHeight = rect.size.height;
    }
    return stringHeight;
}

-(CGFloat)widthForString:(NSString *)value fontSize:(CGFloat)fontSize andHeight:(CGFloat)height
{
    CGSize strSize = CGSizeMake(CGFLOAT_MAX, height);
    NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
    CGFloat stringWidth = 0;
    if (value) {
        CGRect rect = [value boundingRectWithSize:strSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
        stringWidth = rect.size.width;
    }
    return stringWidth;
}

@end
